﻿/*
 * @Autor: PK
 * @Date: 2021/12/21 14:52:SS
 */

using System;
using GeneticAlgorithm;
using GeneticAlgorithm.Components.CrossoverManagers;
using GeneticAlgorithm.Components.MutationManagers;
using GeneticAlgorithm.Interfaces;
using GeneticAlgorithm.StopManagers;
using Reminiscence.Collections;
using ShkSimulation.core.optimization.interfaces;

namespace ShkSimulation.core.optimization.algorithm.classicGeneticAlgotithm {

	public class ClassicGeneticAlgorithm : OptimizationAlgorithm{
		
		public void RunWithOptimization(Optimization optimization) {
			var mutationManager = new DoubleUniformMutationManager(0, 100);
			var evaluator = new BasicEvaluator(optimization);
			var populationGenerator = new DoublePopulationGenerator(optimization.VariableVectorTemplate, mutationManager, evaluator);
			ICrossoverManager crossoverManager = new SinglePointCrossoverManager<double>(mutationManager, evaluator);
			IStopManager stopManager = new StopAtGeneration(5);
			var engineBuilder = new GeneticSearchEngineBuilder(10, 10, crossoverManager, populationGenerator)
				.AddStopManager(stopManager)
				.SetMutationProbability(0.1).SetElitePercentage(0.1);
			GeneticSearchEngine engine = engineBuilder.Build();
			GeneticSearchResult result = engine.Run();
			Console.WriteLine(@"Finished!");
			Console.WriteLine(result.BestChromosome);
		}
		
			
		public ClassicGeneticAlgorithm() {
			
		}

		private int population;
		private int generation;
		private double elite;
		private double mutationProperty;
		private int crosssIndex;
		private int mutationIndex;
		private bool useGenration;
		private bool useGonvergence;
		private double convergence;
		private bool useTarget;
		private double target;

		public ClassicGeneticAlgorithm(int populationSize, 
			int generation, 
			double elite, 
			double mutationProperty, 
			int crosssIndex, 
			int mutationIndex, 
			bool useGenration, 
			bool useGonvergence, double convergence,
			bool useTarget, double target) {
			this.population = populationSize;
			this.generation = generation;
			this.elite = elite;
			this.mutationProperty = mutationProperty;
			this.crosssIndex = crosssIndex;
			this.mutationIndex = mutationIndex;
			this.useGenration = useGenration;
			this.useGonvergence = useGonvergence;
			this.convergence = convergence;
			this.useTarget = useTarget;
			this.target = target;
		}

		public void RunWithOptimization2(Optimization optimization) {
			var mutationManager = new DoubleUniformMutationManager(0, 100);
			var evaluator = new BasicEvaluator(optimization);
			var populationGenerator = new DoublePopulationGenerator(optimization.VariableVectorTemplate, mutationManager, evaluator);
			ICrossoverManager crossoverManager = new SinglePointCrossoverManager<double>(mutationManager, evaluator);
			List<IStopManager> stopManagers = new List<IStopManager>();
			if (useGenration) {
				stopManagers.Add(new StopAtGeneration(generation));
			}
			if (useGonvergence) {
				stopManagers.Add(new StopAtConvergence(convergence));
			}
			if (useTarget) {
				stopManagers.Add(new StopAtEvaluation(target));
			}
			Console.WriteLine(population + "--------------" + generation);
			var engineBuilder = new GeneticSearchEngineBuilder(population, generation, crossoverManager, populationGenerator)
				.SetMutationProbability(mutationProperty).SetElitePercentage(elite);
			foreach (var stopManager in stopManagers) {
				engineBuilder.AddStopManager(stopManager);
			}
			GeneticSearchEngine engine = engineBuilder.Build();
			GeneticSearchResult result = engine.Run();
			Console.WriteLine(@"Finished!");
			Console.WriteLine(result.BestChromosome);
		}


	}
}